/*
 * Copyright (c) 2016
 * Research Group: ERA (Efficient and Resilient Architecture group) 
 * Contributors:  Shijun Gong, Wenyan Lu, Jiajun Li, Shuhao Jiang, Jingya Wu, and Guihai Yan  
 * Affiliation: State Key Laboratory of Computer Architecture, Institute of Computing Technology, Chinese Academy of Sciences
 * Contact Info.:   {gongshijun, yan}@ict.ac.cn
 * Web: http://www.carch.ac.cn/~yan
 * Address:  P.O.Box 2704, Beijing, 100190, China
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * mctrl
 *
 * local memory manipulation definition
 */

#include<stdio.h>

#include "ps_pipeline.h"
#include "mctrl.h"
#include "memop.h"
#include "fileVariant.h"

void Init_mm()
{
	MM_add_start=0;
	MM_add_end=INIT_MEM_SIZE;
	readfile(con_mem_tmp,0,INIT_MEM_SIZE,MM);
}

void load_mm(char *filename,long address,long size)
{
	MM_add_start=address;
	MM_add_end=address+INIT_MEM_SIZE;
	readfile(filename,address, size, MM); //load mm.mem to MM
}

void store_mm(char *filename,long address,long size)
{
	writefile(filename,address,size,MM);
}

short read_mm(long addr)
{
	//printf("--------------------------------------%d\n",MM[addr-MM_add_start]);
	if((addr>=MM_add_start)&&(addr<MM_add_end))
		return MM[addr-MM_add_start].M;
	else
	{
		store_mm(con_mem_tmp,MM_add_start,INIT_MEM_SIZE);
		load_mm(con_mem_tmp,addr,INIT_MEM_SIZE);
		return MM[addr-MM_add_start].M;
	}
}

void write_mm(long addr,short data)
{
	if((addr>=MM_add_start)&&(addr<MM_add_end))
		MM[addr-MM_add_start].M=data;
	else
	{
		store_mm(con_mem_tmp,MM_add_start,INIT_MEM_SIZE);
		load_mm(con_mem_tmp,addr,INIT_MEM_SIZE);
		MM[addr-MM_add_start].M=data;
	}
}

/*
void show_mm(long start,long end)
{
	showfile(con_mem_tmp, start, end); //show content of MM from start to end
}*/
